package upload

import (
	"context"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
	"path/filepath"
	"server/internal/consts"
	"server/internal/model"
	"server/internal/service"
	"strconv"
)

// Uploader 定义文件上传接口
type Uploader interface {
	UploadFile(ctx context.Context, file *ghttp.UploadFile, fileSubject string) (out model.FileUploadOutput, err error)
	DeleteFile(ctx context.Context, key string) (err error)
}

// NewOssClient 根据不同的驱动类型创建文件上传客户端
func NewOssClient(storageType int) Uploader {
	switch storageType {
	case consts.FileUploadStorageTypeLocal:
		return &LocalUpload{}
	case consts.FileUploadStorageTypeAliYunOss:
		return &AliYunOssUpload{}
	case consts.FileUploadStorageTypeTenCentCos:
		return &TenCentUpload{}
	}
	return nil
}

// FormatUploadFileURL 根据文件路径&文件存储类型返回可访问的URL
func FormatUploadFileURL(ctx context.Context, path string, storageType int) string {
	config, err := service.File().GetFileUploadConfig(ctx)
	if err != nil {
		return ""
	}
	switch storageType {
	case consts.FileUploadStorageTypeLocal:
		//反斜杠转换为正斜杠，避免存在转义问题
		return filepath.ToSlash(config.Local.FileServerHost + filepath.Join(config.Local.FileServerStaticURIPath, path))
	case consts.FileUploadStorageTypeAliYunOss:
		// 阿里云的 Bucket 访问URL + 文件KEY
		return config.AliYunOSS.BucketUrl + "/" + path
	case consts.FileUploadStorageTypeTenCentCos:
		// 腾讯云
		return config.TenCentCos.BucketUrl + "/" + path
	default:
		return ""
	}
}

// GenerateUploadFilePath 生成一个文件路径
func GenerateUploadFilePath(ctx context.Context, filename string, storageType int, FileSubject string) string {
	config, err := service.File().GetFileUploadConfig(ctx)
	if err != nil {
		return ""
	}
	basePath := ""
	switch storageType {
	case consts.FileUploadStorageTypeLocal:
		// 本地文件服务的存储前缀目录
		basePath = config.Local.FileServerDIR
	case consts.FileUploadStorageTypeAliYunOss:
		// 阿里云的 Bucket 的基础前缀目录
		basePath = config.AliYunOSS.BasePath
	case consts.FileUploadStorageTypeTenCentCos:
		// 腾讯云
		basePath = config.TenCentCos.BasePath
	}
	year := strconv.Itoa(gtime.Now().Year())
	month := strconv.Itoa(gtime.Now().Month())
	day := strconv.Itoa(gtime.Now().Day())
	return filepath.ToSlash(filepath.Join(basePath, FileSubject, year, month, day, filename))
}
